home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / ScrapColor 1.0 / scrapcolor library / scrapcolor.c next >
Text File  |  1996-06-06  |  7KB  |  304 lines

  1. // scrapcolor.c
  2. //
  3. // Functions and private types to support the scrap color format.
  4. // Version 1.0
  5. // Written by Mark Womack, June 1996.
  6. //
  7. // The code and clipboard format are placed in the public domain
  8. // for the benefit of all. It is hoped that it will become a
  9. // standard used by many applications, commercial and shareware,
  10. // to transfer color information effectively.
  11. //
  12. // The author takes no responsibility damages rendered caused by bugs
  13. // or defects lurking in this code. If you find a bug, please use the
  14. // email address in the accompnaying read me file to contact him.
  15.  
  16. // includes
  17. //
  18. #include "scrapcolor.h"
  19. #include <Picker.h>
  20.  
  21. // private types
  22. //
  23. typedef struct {
  24.     short        model;
  25.     ColorData    colorData;
  26. }ScrapColorData;
  27.  
  28. // private defines
  29. //
  30.  
  31. // the format scrap tag
  32. #define    kScrapColorType    'sCLR'
  33.  
  34. // the current format version
  35. #define kFormatVersion    0x0001
  36.  
  37. // function implementations
  38. //
  39.  
  40. // get single color from scrap in model it is stored as
  41. pascal OSErr GetColorFromScrap(ColorData* theColor, short* theModel)
  42. {
  43. Handle            scrapDataHdl;
  44. Ptr                thePtr;
  45. unsigned short    version;
  46. unsigned short    numColors;
  47. long            size;
  48. long            offset;
  49.  
  50.     scrapDataHdl = NewHandle(0);
  51.     if (scrapDataHdl == NULL)
  52.         return memFullErr;
  53.         
  54.     // try to get the scrap data
  55.     size = GetScrap(scrapDataHdl, kScrapColorType,&offset);
  56.     
  57.     // error returned by GetScrap
  58.     if (size < 0)
  59.     {
  60.         if (scrapDataHdl)
  61.             DisposeHandle(scrapDataHdl);
  62.         return size;
  63.     }
  64.     // nil handle
  65.     else if (scrapDataHdl == NULL)
  66.     {
  67.         return memFullErr;
  68.     }
  69.     // handle not the right size, so must be memFull
  70.     else if (GetHandleSize(scrapDataHdl) != size)
  71.     {
  72.         DisposeHandle(scrapDataHdl);
  73.         return memFullErr;
  74.     }
  75.     // there aren't any colors in the structure
  76.     else if ((*(short*)(*scrapDataHdl)) == 0)
  77.     {
  78.         DisposeHandle(scrapDataHdl);
  79.         return noTypeErr;
  80.     }
  81.     
  82.     // lock this puppy so it doesn't move
  83.     HLock(scrapDataHdl);
  84.     
  85.     thePtr = *scrapDataHdl;
  86.  
  87.     // get and check the version number
  88.     version = *((unsigned short*)thePtr);
  89.     thePtr += sizeof(unsigned short);
  90.  
  91.     // unknown format
  92.     if (version > kFormatVersion)
  93.     {
  94.         HUnlock(scrapDataHdl);
  95.         DisposeHandle(scrapDataHdl);
  96.         return noTypeErr;
  97.     }
  98.     
  99.     // get the number of colors
  100.     numColors = *((unsigned short*)thePtr);
  101.     thePtr += sizeof(unsigned short);
  102.         
  103.     // get the color model
  104.     *theModel = ((ScrapColorData*)thePtr)->model;
  105.     
  106.     // get the color data
  107.     *theColor = ((ScrapColorData*)thePtr)->colorData;
  108.     
  109.     // throw away the scrap data
  110.     HUnlock(scrapDataHdl);
  111.     DisposeHandle(scrapDataHdl);
  112.  
  113.     return noErr;
  114. }
  115.  
  116. // get single color from scrap in the RGB model
  117. pascal OSErr GetRGBColorFromScrap(RGBColor* theColor)
  118. {
  119. ColorData    colorData;
  120. short        colorModel;
  121. OSErr        err;
  122.  
  123.     err = GetColorFromScrap(&colorData,&colorModel);
  124.     if (err)
  125.         return err;
  126.         
  127.     // convert the color info if we have to
  128.     return ConvertColor(&colorData,colorModel,(ColorData*)theColor,kRGBModel);
  129. }
  130.  
  131. // get single color from scrap in the HSL model
  132. pascal OSErr GetHSLColorFromScrap(HSLColor* theColor)
  133. {
  134. ColorData    colorData;
  135. short        colorModel;
  136. OSErr        err;
  137.  
  138.     err = GetColorFromScrap(&colorData,&colorModel);
  139.     if (err)
  140.         return err;
  141.         
  142.     // convert the color info if we have to
  143.     return ConvertColor(&colorData,colorModel,(ColorData*)theColor,kHSLModel);
  144. }
  145.  
  146. // get single color from scrap in the HSV model
  147. pascal OSErr GetHSVColorFromScrap(HSVColor* theColor)
  148. {
  149. ColorData    colorData;
  150. short        colorModel;
  151. OSErr        err;
  152.  
  153.     err = GetColorFromScrap(&colorData,&colorModel);
  154.     if (err)
  155.         return err;
  156.         
  157.     // convert the color info if we have to
  158.     return ConvertColor(&colorData,colorModel,(ColorData*)theColor,kHSVModel);
  159. }
  160.  
  161. // get single color from scrap in the CMY model
  162. pascal OSErr GetCMYColorFromScrap(CMYColor* theColor)
  163. {
  164. ColorData    colorData;
  165. short        colorModel;
  166. OSErr        err;
  167.  
  168.     err = GetColorFromScrap(&colorData,&colorModel);
  169.     if (err)
  170.         return err;
  171.         
  172.     // convert the color info if we have to
  173.     return ConvertColor(&colorData,colorModel,(ColorData*)theColor,kCMYModel);
  174. }
  175.  
  176. // put single color into scrap in given color model (no conversion)
  177. pascal OSErr PutColorIntoScrap(const ColorData* colorData, const short colorModel)
  178. {
  179. Handle            theScrapHdl;
  180. Ptr                thePtr;
  181. ScrapColorData    theScrapColor;
  182. OSErr            theErr;
  183.  
  184.     // create a handle to put the data into
  185.     theScrapHdl = NewHandle(sizeof(unsigned short)*2 + sizeof(ScrapColorData));
  186.     if (!theScrapHdl)
  187.         return memFullErr;
  188.         
  189.     // lock it so it won't move
  190.     HLock(theScrapHdl);
  191.     
  192.     // put the data into the structure
  193.     theScrapColor.model = colorModel;
  194.     theScrapColor.colorData = *colorData;
  195.     
  196.     // set up the pointer that will move
  197.     thePtr = *theScrapHdl;
  198.  
  199.     // put in the format version
  200.     *((unsigned short*)thePtr) = kFormatVersion;
  201.     thePtr += sizeof(unsigned short);    
  202.     
  203.     // there is only one color in the handle
  204.     *((unsigned short*)thePtr) = 1;
  205.     thePtr += sizeof(unsigned short);
  206.     
  207.     // store the first color in the handle
  208.     *((ScrapColorData*)thePtr) = theScrapColor;
  209.         
  210.     // put the data into the scrap
  211.     theErr = PutScrap(GetHandleSize(theScrapHdl),kScrapColorType,(Ptr)*theScrapHdl);
  212.     
  213.     // unlock and dispose of the scrap handle
  214.     HUnlock(theScrapHdl);
  215.     DisposeHandle(theScrapHdl);
  216.     
  217.     return theErr;
  218. }
  219.  
  220. // put single RGB color into the scrap
  221. pascal OSErr PutRGBColorIntoScrap(const RGBColor* theColor)
  222. {
  223.     return PutColorIntoScrap((ColorData*)theColor, kRGBModel);
  224. }
  225.  
  226. // put single HSL color into the scrap
  227. pascal OSErr PutHSLColorIntoScrap(const HSLColor* theColor)
  228. {
  229.     return PutColorIntoScrap((ColorData*)theColor, kHSLModel);
  230. }
  231.  
  232. // put single HSV color into the scrap
  233. pascal OSErr PutHSVColorIntoScrap(const HSVColor* theColor)
  234. {
  235.     return PutColorIntoScrap((ColorData*)theColor, kHSVModel);
  236. }
  237.  
  238. // put single CMY color into the scrap
  239. pascal OSErr PutCMYColorIntoScrap(const CMYColor* theColor)
  240. {
  241.     return PutColorIntoScrap((ColorData*)theColor, kCMYModel);
  242. }
  243.  
  244. // convert from one color model to another
  245. pascal OSErr ConvertColor(const ColorData* oldColor, const short oldModel, ColorData* newColor, const short newModel)
  246. {
  247. RGBColor    theRGBColor;
  248.  
  249.     // if already in desired model, just return
  250.     if (oldModel == newModel)
  251.     {
  252.         *newColor = *oldColor;
  253.         return noErr;
  254.     }
  255.         
  256.     // convert all models to RGB
  257.     switch(oldModel)
  258.     {
  259.         case kRGBModel:
  260.             theRGBColor = *((RGBColor*)oldColor);
  261.             break;
  262.         
  263.         case kHSVModel:
  264.             HSV2RGB((HSVColor*)oldColor,&theRGBColor);
  265.             break;
  266.             
  267.         case kHSLModel:
  268.             HSL2RGB((HSLColor*)oldColor,&theRGBColor);
  269.             break;
  270.             
  271.         case kCMYModel:
  272.             CMY2RGB((CMYColor*)oldColor,&theRGBColor);
  273.             break;
  274.             
  275.         default:
  276.             return noTypeErr;
  277.     }
  278.     
  279.     // now convert the RGB to the desired model
  280.     switch(newModel)
  281.     {
  282.         case kRGBModel:
  283.             *((RGBColor*)newColor) = theRGBColor;
  284.             break;
  285.         
  286.         case kHSVModel:
  287.             RGB2HSV(&theRGBColor,(HSVColor*)newColor);
  288.             break;
  289.             
  290.         case kHSLModel:
  291.             RGB2HSL(&theRGBColor,(HSLColor*)newColor);
  292.             break;
  293.             
  294.         case kCMYModel:
  295.             RGB2CMY(&theRGBColor,(CMYColor*)newColor);
  296.             break;
  297.             
  298.         default:
  299.             return noTypeErr;
  300.     }
  301.     
  302.     return noErr;
  303. }
  304.